package com.zz.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zz.common.R;
import com.zz.entity.Club;
import com.zz.entity.ClubAuditing;
import com.zz.entity.ClubLeader;
import com.zz.entity.User;
import com.zz.mapper.ClubAuditingMapper;
import com.zz.mapper.ClubLeaderMapper;
import com.zz.mapper.ClubMapper;
import com.zz.mapper.UserMapper;
import com.zz.service.ClubService;
import com.zz.utils.AesEncryptUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.Null;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author 朱彦燕
 */
@Service
@Slf4j
@Validated
public class ClubServiceImpl extends ServiceImpl<ClubMapper, Club> implements ClubService {

    @Autowired
    private ClubMapper clubMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private ClubAuditingMapper clubAuditingMapper;

    @Autowired
    private ClubLeaderMapper clubLeaderMapper;

    @Value("${qiniu.fileDomain}")
    private String fileDomain;

    /**
     * 展示管理的所有社团（leader）
     * @param request
     * @return
     */
    @Override
    public R<List<Club>> manageClubList(HttpServletRequest request) {
        // 获取用户名
        String userName = (String) request.getSession().getAttribute("user");

        // 条件查询器->查询当前用户信息
        LambdaQueryWrapper<User> userWrapper = new LambdaQueryWrapper<>();
        userWrapper.eq(User::getName, userName);
        User user = userMapper.selectOne(userWrapper);

        // 查询社团负责人目前管理的社团club_leader表
        LambdaQueryWrapper<ClubLeader> leaderWrapper = new LambdaQueryWrapper<>();
        leaderWrapper.eq(ClubLeader::getUserId, user.getId())
                .eq(ClubLeader::getStatus,1).eq(ClubLeader::getOperate, 1);
        List<ClubLeader> clubLeaders = clubLeaderMapper.selectList(leaderWrapper);
        // 遍历得到所有社团id集合
        Set<Integer> clubIds = new HashSet<>();
        for (ClubLeader clubLeader : clubLeaders) {
            clubIds.add(clubLeader.getClubId());
        }

        // 查询社团负责人id为当前用户学号的社团
        LambdaQueryWrapper<Club> clubWrapper = new LambdaQueryWrapper<>();
        clubWrapper.in(Club::getId, clubIds);

        List<Club> clubs = clubMapper.selectList(clubWrapper);

        return R.success(clubs);
    }

    /**
     * 选择将要管理的社团（leader）
     * @param clubId
     * @param request
     * @return
     */
    @Override
    public R<String> chooseClub(int clubId, HttpServletRequest request) {
        log.info("clubId:{}", clubId);
        request.getSession().setAttribute("club",clubId);

        // 根据社团id获取社团
        Club club = clubMapper.selectById(clubId);

        return R.success(club.getName());
    }

    /**
     * 退出对本社团的管理（leader）
     * @param request
     * @return
     */
    @Override
    public R<String> clubLogout(HttpServletRequest request) {
        Long clubId = (Long) request.getSession().getAttribute("club");
        // 根据社团id获取社团
        Club club = clubMapper.selectById(clubId);

        request.getSession().removeAttribute("club");

        return R.success("成功退出对社团："+club.getName()+"的管理！");
    }


    @Override
    public R<List<Club>> page(@Nullable String clubName, @Nullable String classify) {
        // 条件构造器
        LambdaQueryWrapper<Club> queryWrapper = new LambdaQueryWrapper<>();
        // 添加过滤条件(isNotEmpty(name))
        queryWrapper.like(clubName != null, Club::getName,clubName).
                like(classify != null, Club::getClassify, classify);

        List<Club> clubs = clubMapper.selectList(queryWrapper);
        for (Club club : clubs) {
            String image = club.getImage();
            //图片路径解密
            if (image != null){
                image = AesEncryptUtils.decrypt(image);
                club.setImage(fileDomain+"/"+image);
            }
        }

        int total =  clubs.size();

        return R.success(clubs).add("total", total);
    }

    /**
     * 参加社团
     * @param clubId
     * @param request
     * @return
     */
    @Override
    public R<String> join(int clubId, HttpServletRequest request) {
        // 判断此社团是否存在
        Club club = clubMapper.selectById(clubId);
        if (club == null){
            return R.error("此社团不存在！");
        }
        // 从session中获取用户名
        String userName = (String) request.getSession().getAttribute("user");
        //根据userName查询用户
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getName, userName);
        User user = userMapper.selectOne(wrapper);

        // 用户已经参加3个社团，则不允许在参加社团
        if ((user.getClubId1() == null || user.getClubId1() == 0L) && (user.getClubId2() == null || user.getClubId2() == 0L) && (user.getClubId3() == null || user.getClubId3() == 0L)){
            return R.error("已参加三个社团,加入失败！");
        }

        if (user.getClubId1().equals(clubId) || user.getClubId2().equals(clubId) || user.getClubId3().equals(clubId)){
            return R.error("用户已经参加此社团！");
        }
        // 判断此用户是否已经提交申请
        LambdaQueryWrapper<ClubAuditing> clubAuditingLambdaQueryWrapper = new LambdaQueryWrapper<>();
        clubAuditingLambdaQueryWrapper.eq(ClubAuditing::getClubId, clubId).eq(ClubAuditing::getUserId, user.getId())
                .eq(ClubAuditing::getStatus, 0).eq(ClubAuditing::getOperate, 0);
        ClubAuditing clubAuditing1 = clubAuditingMapper.selectOne(clubAuditingLambdaQueryWrapper);
        if (clubAuditing1 != null){
            return R.error("此用户已经提交加入该社团的申请！不能重复提交申请！");
        }

        // 参加社团审核申请
        ClubAuditing clubAuditing = new ClubAuditing();
        clubAuditing.setClubId(clubId);
        clubAuditing.setUserId(user.getId());
        clubAuditingMapper.insert(clubAuditing);

        return R.success("申请加入社团成功，等待社团负责人审核！");
    }

    /**
     * 退出已经参加的社团
     * @param clubId
     * @param request
     * @return
     */
    @Override
    public R<String> exit(int clubId, HttpServletRequest request) {
        // 从session中获取用户名
        String userName = (String) request.getSession().getAttribute("user");
        //根据userName查询用户
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getName, userName);
        User user = userMapper.selectOne(queryWrapper);

        //删除社团,注意：将社团id变为0L
        if (user.getClubId1().equals(clubId)){
            user.setClubId1(0);
        }else if (user.getClubId2().equals(clubId)){
            user.setClubId2(0);
        }else if (user.getClubId3().equals(clubId)){
            user.setClubId3(0);
        }

        //对数据库进行操作
        userMapper.updateById(user);

        // 将社团人数减少一个
        Club club = clubMapper.selectById(clubId);

        Integer people = club.getPeople();
        club.setPeople(people-1);

        clubMapper.updateById(club);

        return R.success("退出成功！");
    }

    @Override
    public R<String> registerClub(Club club) {
        // 条件查询器
        LambdaQueryWrapper<Club> clubWrapper = new LambdaQueryWrapper<>();
        clubWrapper.eq(Club::getName, club.getName());
        Club club1 = clubMapper.selectOne(clubWrapper);

        if (club1 != null){
            return R.error("此社团已注册！");
        }

        clubMapper.insert(club);

        // 社团负责人表增加一条信息
        ClubLeader clubLeader = new ClubLeader();
        clubLeader.setClubId(club.getId());
        clubLeader.setUserId(club.getLeaderId());
        clubLeader.setStatus(1);
        clubLeader.setOperate(1);
        clubLeaderMapper.insert(clubLeader);

        return R.success("成功注册社团"+club.getName()+"!");

    }

    @Override
    public R<String> editClub(Club club) {
        // 条件查询器
        Club clubOld = clubMapper.selectById(club.getId());
        // 更新社团信息:社团名称和编码不允许修改
        clubOld.setAcademy(club.getAcademy());
        clubOld.setTeacher(club.getTeacher());
        clubOld.setLeaderId(club.getLeaderId());
        clubOld.setPhone(club.getPhone());
        clubOld.setIntroduce(club.getIntroduce());
        // 更新数据库
        clubMapper.updateById(clubOld);

        return R.success("成功修改社团信息！");
    }

    @Override
    public R<Club> clubInfo(int clubId) {
        // 查询数据库
        Club club = clubMapper.selectById(clubId);

        return R.success(club);
    }
}
